package StampedLock_16;
import java.util.concurrent.locks.StampedLock;

public class 乐观读与锁升级 {
    private static final StampedLock lock = new StampedLock();
    private static int balance = 1000;
    private static final int THREAD_COUNT = 10;

    public static void main(String[] args) {
        for (int i = 0; i < THREAD_COUNT; i++) {
            final int threadId = i;
            new Thread(new Runnable() {
                public void run() {
                    if (threadId % 3 == 0) {
                        // 写线程
                        transfer(threadId, 100);
                    } else {
                        // 读线程
                        checkBalance(threadId);
                    }
                }
            }, "Thread-" + i).start();
        }
    }

    private static void checkBalance(int threadId) {
        long stamp = lock.tryOptimisticRead();
        int currentBalance = balance;

        // 模拟读取耗时
        try {
            Thread.sleep((long)(Math.random() * 50));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        if (!lock.validate(stamp)) {
            // 乐观读失败，转为悲观读
            stamp = lock.readLock();
            try {
                currentBalance = balance;
            } finally {
                lock.unlockRead(stamp);
            }
        }
        System.out.println(Thread.currentThread().getName() + " 检查余额: " + currentBalance);
    }

    private static void transfer(int threadId, int amount) {
        long stamp = lock.writeLock();
        try {
            System.out.println(Thread.currentThread().getName() + " 开始转账操作");
            Thread.sleep(100); // 模拟转账耗时
            balance += amount;
            System.out.println(Thread.currentThread().getName() + " 转账完成，新余额: " + balance);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlockWrite(stamp);
        }
    }
}